import re
from importlib import import_module
from django.db import models
from django.db.models import Q
import pandas as pd
from config.constant import (
    QQ_ID_MAX_LENGTH,
    GROUP_NAME,
    DIRECTION_NAME,
    MAX_MARKDOWN_SIZE,
    TASK_STATUS,
    NOT_FOUND,
    NOT_VALID,
    MAX_EVALUATE_SIZE,
    MINIMUM_WORK_TIME,
    DEFAULT_FILE_MANAGER,
    DEFAULT_CONFIG_PATH,
)
from apps.base_app.utils import (
    Thread, get_md5,
)
from datetime import (
    datetime,
    timedelta,
)

__utils = import_module(DEFAULT_CONFIG_PATH)
assert hasattr(__utils, DEFAULT_FILE_MANAGER), ImportError('配置的文件管理器不存在！')
FileManager = getattr(__utils, DEFAULT_FILE_MANAGER)


class Direction:  # 每个方向的作业都一样，即使是不同小组，所以下面的表暂时均使用此表的`主键`
    group = GROUP_NAME  # 实际上的格式为 (idx, name)
    direction = DIRECTION_NAME  # 实际上的格式为 (idx, name)
    # 之后的作业、学员的信息统一用此“表”作为标识：{id: {'group':xxx, 'direction':xxx}}
    pk = id = {uid: info for uid, info in enumerate(
        [{'group': gp, 'direction': dt} for dt in DIRECTION_NAME for gp in GROUP_NAME]
    )}

    @classmethod
    def get(cls, pk: int) -> dict:
        """
        通过主键id获取组和方向的信息
        :param pk: 主键id
        :return: {'group': (idx, name), 'direction': (idx, name)}
        """
        return cls.pk.get(pk, NOT_FOUND)

    @classmethod
    def get_group(cls, pk) -> str:
        """
        获取组名
        :param pk: 主键id
        :return: 适应期xx组
        """
        return cls.get(pk).get('group')[1] if cls.get(pk) else NOT_FOUND

    @classmethod
    def get_direction(cls, pk) -> str:
        """
        获取方向名
        :param pk: 主键id
        :return: 开发
        """
        return cls.get(pk).get('direction')[1] if cls.get(pk) else NOT_FOUND

    @classmethod
    def get_pk(cls, group: str | int, direction: str | int) -> int:
        if isinstance(direction, int):
            direction = DIRECTION_NAME[direction][1]
        if isinstance(group, int):
            group = GROUP_NAME[group][1]
        for pk, info in cls.pk.items():
            if info['group'][1] == group and info['direction'][1] == direction:
                return pk
        else:
            return NOT_FOUND

    @classmethod
    def get_groups(cls, direction: str | int) -> list[int]:
        """
        通过部门获取组pk
        :param direction: 方向名或方向编号
        :return:
        """
        res = []
        if isinstance(direction, int):
            direction = DIRECTION_NAME[direction][1]
        for pk, info in cls.pk.items():
            if info['direction'][1] == direction:
                res.append(pk)
        return res

    @classmethod
    def get_directions(cls, group: str | int) -> list[int]:
        """
        通过部门获取组pk
        :param group: 组名或组编号
        :return:
        """
        res = []
        if isinstance(group, int):
            group = GROUP_NAME[group][1]
        for pk, info in cls.pk.items():
            if info['group'][1] == group:
                res.append(pk)
        return res

    @classmethod
    def get_direction_id(cls, s):
        for i in cls.direction:
            if i[1] == s:
                return i[0]
        return NOT_FOUND


# 学长、学弟的公共信息表
class CommonInfo(models.Model):
    name = models.CharField(max_length=7, verbose_name='姓名')
    stu_id = models.CharField(max_length=10, unique=True, verbose_name='学号')
    password = models.CharField(max_length=32, verbose_name='密码')
    qq_id = models.CharField(max_length=QQ_ID_MAX_LENGTH, verbose_name='QQ号')  # 目前最长10位，未来可能会更长
    dg_id = models.IntegerField(verbose_name='对应的方向+部门编号')
    is_active = models.BooleanField(default=False, verbose_name='通过')  # 学长学姐是否通过了他的注册

    # 用于以后功能拓展和密码找回，暂时未启用
    email = models.EmailField(blank=True, null=True, verbose_name='邮箱')
    phone = models.CharField(blank=True, null=True, verbose_name='电话', max_length=11)

    fields = ['qq_id', 'is_active', 'email', 'phone', 'name']
    register_fields = ['name', 'stu_id', 'qq_id', 'group', 'direction', 'email', 'phone', 'password']

    class Meta:
        abstract = True

    @classmethod
    def get_qq_id(cls, pk):
        temp = cls.objects.filter(pk=pk)
        return temp.first().qq_id if temp.first() else NOT_FOUND

    @classmethod
    def get_stu_id(cls, pk):
        temp = cls.objects.filter(pk=pk)
        return temp.first().stu_id if temp.first() else NOT_FOUND

    @classmethod
    def get_pk(cls, stu_id: str = None, qq_id: str = None) -> int:
        """
        通过学生号或QQ号来获取 `user` 表的对应人的主键🗡
        :param stu_id: 学生号
        :param qq_id: QQ号
        :return: pk
        """
        if not stu_id or not qq_id:
            temp = cls.objects.filter(**({'stu_id': stu_id} if stu_id else {'qq_id': qq_id}))
        else:
            temp = cls.objects.filter(stu_id=stu_id, qq_id=qq_id)
        return temp.first().pk if temp.first() else NOT_FOUND

    @classmethod
    def get_name(cls, pk):
        temp = cls.objects.filter(pk=pk)
        return temp.first().name if temp.first() else NOT_FOUND

    @classmethod
    def pass_is_active(cls, pks):
        res = cls.objects.filter(pk__in=pks).update(is_active=True)
        return res

    @classmethod
    def is_exist(cls, **data: dict) -> bool:
        """
        判断 data 提供的信息是否存在
        :param data: name, stu_id, qq_id, password(md5), pk, phone, ...字段名
        :return: bool
        """
        return bool(cls.objects.filter(**data).first())

    @classmethod
    @property
    def is_senior(cls):
        raise SyntaxError('此方法必须被子类继承')

    @classmethod
    def register(cls, **kwargs) -> int:
        """
        密码会自己md5，部门和组会自己填编号，传进来就创建，所以传之前得校验
        :param name: 必填
        :param stu_id: 必填
        :param qq_id: 必填
        :param dg_id: 必填
        :param password: 必填
        :param phone: 选填
        :param email: 选填
        :param kwargs: 略
        :return: pk，创建失败会返回 NOT_VALID
        """
        try:  # 啊啊啊啊啊，摆烂啦，啊啊啊啊啊，后端写成史了，后端集体摆烂啦，啊啊啊，集体，啊啊啊啊啊😫
            pk = cls.objects.create(**({field: kwargs.get(field) for field in cls.register_fields if (
                    field != 'password' and field != 'direction' and field != 'group')} |
                                       {'password': get_md5(kwargs.get('password'))} | {'dg_id': Direction.get_pk(
                        group=kwargs.get('group'), direction=kwargs.get('direction'))})).pk
        except:
            return NOT_VALID
        return pk

    @classmethod
    def serializers(cls, query_set) -> dict:
        """
        将 Django 的格式转化为 前端要的格式：{id: {'name': str, group: str, ...}, ...}
        :param query_set: Django 的数据库映射
        :return: 前端要的格式
        """
        data = {}
        for obj in query_set:
            data[obj.pk] = {
                'name': obj.name,
                'stu_id': obj.stu_id,
                'qq_id': obj.qq_id,
                'group': Direction.get_group(obj.dg_id),
                'direction': Direction.get_direction(obj.dg_id),
                'email': obj.email if obj.email else obj.qq_id + '@qq.com',
                'phone': obj.phone,
                'is_senior': cls.is_senior,
                'is_root': obj.is_root if cls.is_senior else False,
                'work_list': {} if cls.is_senior else WorkList.serializers(WorkList.get_works(obj.pk)),
            }
        return data


class WhoStillWithUs(models.Manager):  # 继承django的QuerySet管理类，已达到筛选结果不一样的结果
    def get_queryset(self):
        # 继承django的查询管理类，重写查询方法以达到修改返回值的效果
        return super(WhoStillWithUs, self).get_queryset().filter(accompany=True)


class StudentsList(CommonInfo):  # 学员表，继承公共信息模板
    accompany = models.BooleanField(default=True)  # 是否还和云顶在一起
    """
    重新定义objects，覆盖django自动生成的objects，当然，如果名字为emm = whoStillWithUs()
    那么在这个表就是：students_list.emm.all()而不是students_list.objects.all()
    """
    objects = WhoStillWithUs()
    objects_all = models.Manager()

    @classmethod
    @property
    def is_senior(cls):
        return False

    @classmethod
    def fuzzy_search(cls, s):  # 例如：搜 2 会把组、名字、等等等都包含个遍
        return cls.objects.filter(
            Q(name__icontains=s) | Q(stu_id__icontains=s) | Q(qq_id__icontains=s) | Q(
                email__icontains=s) | Q(phone__icontains=s)  # 组和方向需要转换！！！！TODO | Q(dg_id__icontains=s) 先不支持
        )

    @classmethod
    def filter_search(cls, **kwargs) -> 'QrSet':  # 先筛选，后搜索
        """
        返回 QrSet，用来搜学生
        :param group: 组编号或组名
        :param direction: 方向编号或方向名
        :param qq_id: QQ号
        :param dg_id: 方向+组编号，优先级比分开的高
        :param is_active: 允许注册否
        :param email: 邮件
        :param phone: 电话
        :param name: 名字
        :param fuzzy: 模糊搜索
        :return: QrSet
        """
        temp = cls.objects.all()
        if dg_id := kwargs.get('dg_id', None):
            temp = temp.filter(dg_id=dg_id)
        if (group := kwargs.get('group', None)) | (direction := kwargs.get('direction', None)):
            if group and direction:
                dg_id = Direction.get_pk(group, direction)
                temp = temp.filter(dg_id=dg_id)
            elif group:
                dg_ids = Direction.get_directions(group)
                temp = temp.filter(dg_id__in=dg_ids)
            else:
                dg_ids = Direction.get_groups(direction)
                temp = temp.filter(dg_id__in=dg_ids)
        for field in cls.fields:
            cont = kwargs.get(field, None)
            if cont:
                temp = temp.filter(**{field: cont})
        fuzzy = kwargs.get('fuzzy', None)
        if fuzzy:
            for field in cls.fields:
                if field == 'is_active':  # 不模糊筛选 is_active
                    continue
                temp = temp.filter(**{field + '__icontains': fuzzy})
        return temp

    # TODO 有时间把链式传递的筛选写一下，这样方便一点


class SeniorList(CommonInfo):  # 学长表，继承公共信息模板
    is_root = models.BooleanField(default=False, verbose_name='root用户')  # 默认不是root

    @classmethod
    @property
    def is_senior(cls):
        return True


class WorkList(models.Model):  # 作业表，即学生的提交作业的表，，，
    students_list_pk = models.IntegerField(verbose_name='学生表主键')
    work_manage_pk = models.IntegerField(verbose_name='作业布置表的主键')  # 实际上是存作业的id，即WorkManage表的主键
    file_name = models.CharField(verbose_name="作业路径", max_length=300)  # 作业链接 # TODO 以后统一一下名字...
    remark = models.TextField(max_length=MAX_MARKDOWN_SIZE, null=True, blank=True)  # 学子的留言，markdown，3M
    time = models.DateTimeField(verbose_name='提交时间')
    normative = models.BooleanField(verbose_name='是否命名规范')  # 是否规范命名
    out_time = models.BooleanField(verbose_name='超时与否')  # 是否超时
    dg_id = models.IntegerField(verbose_name='对应的方向+部门编号')

    # 被谁检查了，在某个人请求下载时就是某个人检查了
    checker = models.CharField(null=True, max_length=300, verbose_name='检查者')  # 使用英文逗号分割检查者的名字，记得转义

    @classmethod
    def dumps_checkers(cls, s: list[str]) -> str:
        """
        将字符串脱敏后拼接
        :param s: 检查者的名字列表
        :return: str
        """
        for i in range(len(s)):
            s[i] = s[i].replace(r',', r'\,')
        return ','.join(s)

    @classmethod
    def loads_checker(cls, s) -> list:
        """
        从脱敏拼接的字符串中还原为检查者的列表：a,b,... -> [a, b, ...]
        :param s: 数据库中脱敏拼接的字符串
        :return: 没有脱敏的名字列表
        """
        if not s:
            return []
        temp_list = re.split(r'(?<!\\),', s)
        for i in range(len(temp_list)):
            temp_list[i] = temp_list[i].replace(r'\,', r',')
        return temp_list

    @classmethod
    def load_evaluate(cls, pk):
        """
        从评价表中获取该与作业有关的评价
        :param pk: 此表的主键
        :return: {'name': [{'time':xx, 'msg': 'xx', 'stars': int}], ...}
        """
        return Evaluate.get_evaluates(pk)

    @classmethod
    def get(cls, pk) -> 'QrSet':
        """
        通过主键拿一个对象
        :param pk: 主键
        :return: QrSet
        """
        return cls.objects.filter(pk=pk).first() if cls.objects.filter(pk=pk).first() else NOT_FOUND

    @classmethod
    def is_exist(cls, data):
        """
        检测符合data字段的是否存在
        :param data:
        :return:
        """
        return bool(cls.objects.filter(**data).first())

    @classmethod
    def add_checker(cls, pk, s) -> None:
        """
        将名字 s 添加到数据库
        :param pk: 评价的表
        :param s: 评价字符串
        :return: None
        """
        temp = cls.objects.filter(pk=pk)
        s = s.replace(',', r'\,')
        if temp.first():
            temp.update(
                checker=f'{f"{temp.first().checker},{s}" if temp.first().checker else s}'
            )

    @classmethod
    def add_evaluate(cls, pk, name, evaluate, stars):
        return Evaluate.create_evaluate(pk, name, evaluate, stars)

    @classmethod
    def delete_checker(cls, pk, s):
        """
        删除 s 这个检查者，只删除一次
        :param pk:
        :param s:
        :return:
        """
        temp = cls.objects.filter(pk=pk)
        if temp.first():
            temp_ss = temp_s = temp.first().checker
            if s in temp_s:
                temp_ss = temp_s.replace(',' + s, '', 1)
                if temp_s == temp_ss:
                    temp_ss = temp_s.replace(s, '', 1)
            temp.update(checker=temp_ss)

    @classmethod
    def delete_evaluate(cls, pk=None, evaluate_pk=None):
        return Evaluate.delete_evaluate(evaluate_pk, pk)

    @classmethod
    def submit(cls, students_list_pk, work_manage_pk, file_name, file: bytes, remark, dg_id, normative):
        """
        交作业，文件名需要在线校验！
        :return:
        """
        work = WorkManage.objects.filter(pk=work_manage_pk).first()
        if not work:
            return NOT_FOUND
        if cls.is_exist({'students_list_pk': students_list_pk, 'dg_id': dg_id}):
            temp = cls.objects.filter(**{'stu_id': students_list_pk, 'dg_id': dg_id})
            FileManager.remove(temp.first().file_name)
            temp.delete()
        out_time = datetime.now() <= work.DDL
        cls.upload(file_name, file)
        cls.objects.create(
            students_list_pk=students_list_pk, work_manage_pk=work_manage_pk, file_name=file_name, remark=remark,
            dg_id=dg_id, normative=normative, out_time=out_time,
        )

    @classmethod
    def upload(cls, file_name, byte):
        """
        只管上传文件的一系列逻辑，之后加入任务管理器、条件管理器后引入线程
        :return:
        """
        # task_pk = TaskList.create_task()   暂时不开了
        FileManager.save(file_name, byte)

    @classmethod
    def download(cls, file_name) -> bytes:
        """
        下载文件的一系列逻辑
        :return:
        """
        return FileManager.read(file_name)

    @classmethod
    def get_works(cls, students_list_pk: int) -> 'QrSet':
        """
        通过学生表的主键获取他的作业 query set
        :param students_list_pk: 在学生表对应的主键
        :return: query set
        """
        temp = cls.objects.filter(students_list_pk=students_list_pk)
        return temp if temp.first() else NOT_FOUND

    @classmethod
    def serializers(cls, query_set) -> dict:
        """
        将作业表的 query set 转化为前端要的格式： {id: {'work': 作业布置表的主键, file_name: 作业路径, ...}}
        :param query_set:
        :return:
        """
        data = {}
        if query_set == NOT_FOUND:
            return data
        for work in query_set:
            data[work.pk] = {
                'work': work.work_manage_pk,
                'time': work.time,
                'normative': work.normative,
                'out_time': work.out_time,
                'remark': work.remark,
                'file_name': work.file_name,
                'self': work.students_list_pk,  # 表示自己在学生表的主键
                'checker': cls.loads_checker(work.checker),
                'evaluate': cls.load_evaluate(work.pk),
                'stars': cls.load_stars(work.pk),
            }
        return data

    @classmethod
    def load_stars(cls, pk):
        """
        拿取该 pk 的平均星星
        :param pk:
        :return:
        """
        return Evaluate.get_avg_stars(pk)

    """
    将数据整理成字典
    就是：{
            'pk': {
                'xx': 'xxx', ...,
                'checker': [xx, xx, xx], 
                'evaluate':{'name': [{'time':xx, 'msg': 'xx', 'stars': int}], ...}
            }
    }
    经过考虑，evaluate改为独立的一个表
    """

    @classmethod
    def get_owner(cls, file_name) -> dict:
        """
        通过作业名字获取主人的信息
        :param file_name:
        :return: {name: ...}
        """
        temp = cls.objects.filter(file_name=file_name)
        if not temp.first():
            return NOT_FOUND
        owner = {
            'name': StudentsList.get_name(temp.first().students_list_pk),
            'qq_id': StudentsList.get_qq_id(temp.first().students_list_pk),
            'stu_id': StudentsList.get_stu_id(temp.first().students_list_pk),
        }
        return owner


class Evaluate(models.Model):
    work_list_pk = models.IntegerField(verbose_name='对应的作业表主键')
    name = models.CharField(max_length=5, verbose_name='留言者的名字')
    evaluate = models.CharField(null=True, max_length=MAX_EVALUATE_SIZE, verbose_name='评价')  # 学长学姐对作业的评价
    stars = models.SmallIntegerField(verbose_name='评分')  # 学长学姐对作业的评分，满分5分
    time = models.DateTimeField(auto_now_add=True)

    @classmethod
    def get_evaluates(cls, work_list_pk) -> dict:  # 缺点：name 为key万一两个张伟...
        """
        获取与WorkList表的pk相关的评论
        :param work_list_pk: WorkList表的主键
        :return: {'name': [{'time':xx, 'msg': 'xx', 'stars': int}], ...}
        """
        temp = cls.objects.filter(work_list_pk=work_list_pk)
        res = {}
        if temp.first():  # 说明有东西
            for i in temp:
                if i.name in res:
                    res[i.name].append({'time': str(i.time), 'msg': i.evaluate, 'stars': i.stars})
                else:
                    res[i.name] = [{'time': str(i.time), 'msg': i.evaluate, 'stars': i.stars}]
        return res

    @classmethod
    def create_evaluate(cls, work_list_pk, name, evaluate, stars):
        res = cls.objects.create(work_list_pk=work_list_pk, name=name, evaluate=evaluate, stars=stars)
        return res

    @classmethod
    def delete_evaluate(cls, pk=None, work_list_pk=None) -> int:
        """
        pk是评价表的主键，work_list_pk是作业表的主键，两个必须且只能存在一个
        删pk=pk，或者删一堆：work_list_pk=work_list_pk
        :param pk: 评价表的主键
        :param work_list_pk: 作业表的主键
        :return: 删除的评论个数
        """
        assert pk or work_list_pk, ValueError('俩你总得传一个吧！？？')
        res = cls.objects.filter(**({'pk': pk} if pk else {'work_list_pk': work_list_pk})).delete()
        return res

    @classmethod
    def get_avg_stars(cls, work_list_pk, default=NOT_FOUND) -> float:
        """
        获得平均评分
        :param work_list_pk:
        :param default: 默认为 NOT_FOUND，定义在 constant.py
        :return:
        """
        temp_list = cls.objects.filter(work_list_pk=work_list_pk)
        if not temp_list.first():
            return default
        res = sum(temp_list.values('stars')) / len(temp_list.values('stars'))
        return res


# 学长布置作业的表，,,
class WorkManage(models.Model):
    name = models.CharField(max_length=28, verbose_name='作业标题')
    message = models.TextField(max_length=MAX_MARKDOWN_SIZE, verbose_name='任务介绍')  # 储存markdown文本，上限3M
    DDL = models.DateTimeField(verbose_name='结束时间')
    direction = models.IntegerField(choices=DIRECTION_NAME, verbose_name='方向')

    # regex = models.CharField(max_length=120, verbose_name='匹配规则')   # 放弃使用

    @classmethod
    def get_pks(cls, name) -> list:
        """
        通过作业名字来获取主键id，但是由于不同方向的作业名字可能一样，所以是获取pks
        :param name: 作业名字
        :return: [(id, direction), ...]
        """
        temp = cls.objects.filter(name=name)
        return temp.values(['id', 'direction']) if temp.first() else NOT_FOUND

    @classmethod
    def get_pk(cls, name, direction) -> int:
        """
        相同方向的作业名字肯定就一样了
        :param name: 作业名字
        :param direction: 部门编号，定义在 constant.py 中的 DIRECTION_NAME 中
        :return: pk
        """
        temp = cls.objects.filter(name=name, direction=direction)
        return temp.first().pk if temp.first() else NOT_FOUND

    @classmethod
    def is_valid(cls, DDL) -> bool:
        """
        判断DDL是否在今天之前，人话：时间是否布置对了
        :param DDL:
        :return: Bool
        """
        if DDL < datetime.now() + timedelta(**MINIMUM_WORK_TIME):
            return False
        return True

    @classmethod
    def assign_work(cls, name, message, DDL, direction: int) -> int:
        """
        布置作业，相同名称、相同方向的作业只能布置一次，第二次就覆盖
        :return: pk
        """
        if isinstance(DDL, str):
            DDL = pd.to_datetime(DDL)
        if not cls.is_valid(DDL):
            return NOT_VALID
        if (temp := cls.objects.filter(name=name, direction=direction)).first():
            temp.update(name=name, message=message, DDL=DDL, direction=direction)
            return temp.first().pk
        return cls.objects.create(name=name, message=message, DDL=DDL, direction=direction).pk

    @classmethod
    def serializers(cls, query_set) -> dict:
        """
        将作业描述表的 QrSet 转化为前端要的格式
        :param query_set:
        :return:
        """
        data = {}
        if query_set == NOT_FOUND:
            return {}
        for info in query_set:
            data[info.pk] = {
                'name': info.name,
                'message': info.message,
                'DDL': info.DDL,
            }
        return data

# class TaskList(models.Model):        # 暂时不开了
#     """
#     这个表用来储存各个任务的进度；这个任务不是作业，而是：文件上传任务、延时提醒任务等等
#     分别有：预约任务表的状态，任务编号，等等
#     一般直接返回一个任务编号作为备用
#     """
#     status = models.SmallIntegerField(choices=TASK_STATUS, verbose_name='任务进度')
#     time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
#
#     @classmethod
#     def create_task(cls) -> int:
#         """
#         创建一个空任务，返回任务的 pk
#         :return: pk
#         """
#         return cls.objects.create(0).pk
#
#     @classmethod
#     def get_status(cls, pk) -> int:
#         """
#         通过 pk 来查询目前状态
#         :param pk: pk
#         :return: 返回状态码
#         """
#         return cls.objects.filter(pk=pk).first().pk if cls.objects.filter(pk=pk).first() else NOT_FOUND
#
#     @classmethod
#     def get_status_str(cls, pk) -> dict:
#         """
#         通过 pk 来获得目前状态描述字典
#         :param pk:
#         :return: {'waiting': bool, 'status': int, 'running': bool, 'done': bool, 'fail': bool}
#         """
#         # return cls.objects.filter(pk=pk).first().get_status_display()
#         # 由于之后可能会扩展，所以，上面代码就不用了
#         template = {'waiting': False, 'status': 0, 'running': False, 'done': False, 'fail': False}
#         match (_ := cls.get_status(pk)):
#             case 0:
#                 template['waiting'] = True
#             case -1:
#                 template['fail'] = True
#             case 101:
#                 template['done'] = True
#             case _:
#                 template['status'] = _
#                 template['running'] = True
#         return template
#
#     @classmethod
#     def update_task(cls, pk, status):  # 之后有机会拓展用状态字典更新状态
#         return cls.objects.filter(pk=pk).update(status=status)
#
#     @classmethod
#     def wrapper_task(cls):
#         """
#         之后会拓展包装一个任务，然后实时监督与更新，目前就先 pass 吧
#         :return:
#         """
#         pass
